package com.mengye.socket.parkourWebSocket;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Semaphore;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.alibaba.fastjson.JSONObject;
import com.mengye.socket.https.PostParkourMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

/**
 * websocket 消息处理
 * 
 * @author mll
 */
@Component
@ServerEndpoint("/websocket/parkour")
public class WebSocketServer
{
    /**
     * WebSocketServer 日志控制器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);

    /**
     * 默认最多允许同时在线人数100
     */
    public static int socketMaxOnlineCount = 20000;

    private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) throws Exception
    {
        String query = session.getRequestURI().getQuery();
        // 连接时候传入的map  比如 token=Bear msg
        // key就是token msg 就是msg
        Map<String, Object> parameters = new HashMap<>();
        String[] pairs = query.split("&");
        for (String pair : pairs)
        {
            int index = pair.indexOf("=");
            String key = pair.substring(0, index);
            String value = pair.substring(index + 1);
            parameters.put(key, value);
        }
        parameters.put(session.getId(),session);
        boolean semaphoreFlag = false;
        // 尝试获取信号量
        semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
        if (!semaphoreFlag)
        {
            // 未获取到信号量
            LOGGER.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount);
            WebSocketUsersParkour.sendMessageToUserByText(session, "当前在线人数超过限制数：" + socketMaxOnlineCount);
            session.close();
        }
        else
        {
            // 添加用户
            WebSocketUsersParkour.put(session.getId(), session);
            WebSocketUsersParkour.putParam(session.getId(),parameters);
            LOGGER.info("\n 建立连接 - {}", session);
            LOGGER.info("\n 当前人数 - {}", WebSocketUsersParkour.getUsers().size());
//            WebSocketUsersParkour.sendMessageToUserByText(session, "连接成功");
        }
    }

    /**
     * 连接关闭时处理
     */
    @OnClose
    public void onClose(Session session)
    {
        LOGGER.info("\n 关闭连接 - {}", session);
        // 移除用户
        WebSocketUsersParkour.remove(session.getId());
        // 获取到信号量则需释放
        SemaphoreUtils.release(socketSemaphore);
    }

    /**
     * 抛出异常时处理
     */
    @OnError
    public void onError(Session session, Throwable exception) throws Exception
    {
        if (session.isOpen())
        {
            // 关闭连接
            session.close();
        }
        String sessionId = session.getId();
        LOGGER.info("\n 连接异常 - {}", sessionId);
        LOGGER.info("\n 异常信息 - {}", exception);
        // 移出用户
        WebSocketUsersParkour.remove(sessionId);
        // 获取到信号量则需释放
        SemaphoreUtils.release(socketSemaphore);
    }

    /**
     * 服务器接收到客户端消息时调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session) throws Exception {
        JSONObject jsonObject = JSONObject.parseObject(message);
        String interfaceName = jsonObject.get("data").toString();
        HashMap<Object, Object> retrunMap = new HashMap<>();
        retrunMap.put("code",jsonObject.get("code"));
        retrunMap.put("msg","");
        // 获取用户token
        Map<String, Map<String, Object>> usersParam = WebSocketUsersParkour.getUsersParam();
        Map<String, Object> map = usersParam.get(session.getId());
        Object token = map.get("token");
        if (ObjectUtils.isEmpty(token)){
            WebSocketUsersParkour.sendMessageToUserByText(session, JSONObject.toJSONString(retrunMap));
            return;
        }
        HashMap<String, String> map1 = new HashMap<>();
        map1.put("Authorization",token.toString());
        String response = PostParkourMessage.doGet( interfaceName, map1);
        retrunMap.put("data",response);
        WebSocketUsersParkour.sendMessageToUserByText(session, JSONObject.toJSONString(retrunMap));
    }
}
